// 消除异步传染性

// 同步请求，函数开始 -> 执行fetch -> 引发错误 -> 函数结束 -> fetch获取结果data ->缓存data  -> 函数开始 -> 函数结束 -> 缓存data -> 函数开始 -> 执行fetch -> 引发错误 -> 函数结束 -> 缓存data -> 函数开始 -> 执行fetch -> 引发错误 -> 函数结束 -> 缓存data -> 函数开始 -> 执行fetch -> 引发错误 -> 函数结束 -> 缓存data -> 函数开始 -> 执行fetch -> 引发错误 -> 函数结束 -> 缓存data -> 函数开始 -> 执行fetch -> 交付data -> 顺序执行函数
function getUser() {
  return fetch('https://api.github.com/users/yygmind')
}

function m1() {
  return getUser()
}

function m2() {
  return m1()
}

function m3() {
  return m2()
}
function main() {
  const user = m3()
  return user
}

function run(func) {
  let cache = []
  let i = 0
  const _originalFetch = window.fetch
  window.fetch = (...args) => {
    // 有缓存
    if (cache[i]) {
      //交付结果
      if (cache[i].status === 'fulfilled') {
        return cache[i].data
      } else if (cache[i].status === 'rejected') {
        // 抛出异常
        throw cache[i].error
      }
    }
    const result = {
      status: 'pending',
      data: null,
      error: null,
    }
    cache[i++] = result

    // 发送请求
    const prom = _originalFetch(...args)
      .then((res) => res.json())
      .then(
        (resp) => {
          result.status = 'fulfilled'
          result.data = resp
        },
        (err) => {
          result.status = 'rejected'
          result.error = err
        }
      )
    // 报错
    throw prom
  }
  try {
    func()
  } catch (err) {
    if (err instanceof Promise) {
      const reRun = () => {
        i = 0
        func()
      }
      err.then(reRun, reRun)
    }
  }
}

run(main)
